package com.imooc.uaa.service;

import com.imooc.uaa.domain.Auth;
import com.imooc.uaa.domain.User;
import com.imooc.uaa.reository.RoleRepo;
import com.imooc.uaa.reository.UserRepo;
import com.imooc.uaa.util.JwtUtil;
import com.imooc.uaa.config.Constants;
import lombok.RequiredArgsConstructor;

import lombok.val;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import java.util.Set;


@RequiredArgsConstructor
@Service
public class UserService {
    private final UserRepo userRepo;
    private final PasswordEncoder passwordEncoder;
    private final JwtUtil jwtUtil;
    private final RoleRepo roleRepo;

    @Transactional
    public User register(User user) {
        return roleRepo.findOptionalByAuthority(Constants.ROLE_USER).map(role -> {
            val userToSave = user
                    .withAuthorities(Set.of(role))
                    .withPassword(passwordEncoder.encode(user.getPassword()));
            return userRepo.save(userToSave);
        }).orElseThrow();
    }

    public Auth login(String username, String password) throws AuthenticationException {
        return userRepo.findOptionalByUsername(username).filter(user -> passwordEncoder.matches(password, user.getPassword())).map(user -> new Auth(jwtUtil.createAccessToken(user), jwtUtil.createRefreshToken(user))).orElseThrow(() -> new BadCredentialsException("用户名或密码错误"));
    }

    /**
     * 判断用户名是否存在
     *
     * @param username 用户名
     * @return 存在与否
     */
    public boolean isUsernameExist(String username) {
        return userRepo.countByUsername(username) > 0;
    }

    /**
     * 判断邮箱是否存在
     *
     * @param email 邮箱地址
     * @return 存在有否
     */
    public boolean isEmailExist(String email) {
        return userRepo.countByEmail(email) > 0;
    }

    /**
     * 判断手机号是否存在
     *
     * @param mobile 手机号
     * @return 存在与否
     */
    public boolean isMobileExist(String mobile) {
        return userRepo.countByMobile(mobile) > 0;
    }
}
